package slidingWindow;

import java.util.HashSet;
import java.util.Set;

public class LengthOfLongestSubstring {

    /**
     * LeetCode T3 无重复字符的最长子串
     * 给定一个字符串，请你找出其中不含有重复字符的 最长子串 的长度。
     * @param args
     */
    public static void main(String[] args) {

    }

    public static int lengthOfLongestSubstring(String s){
        if (s == null || s.length() == 0){
            return 0;
        }
        int len = s.length();
        //定义一个变量存储窗口数据，后面的需要与之比较
        Set<Character> set = new HashSet<>();

        int maxLen = 0;
        //初始化滑动窗口
        for (int i = 0; i < len; i++){
            if (!set.contains(s.charAt(i))){
                //前指针向前运动
                set.add(s.charAt(i));
                maxLen = Math.max(set.size(), maxLen);
            } else {
                //后指针向前运动
                set.remove(s.charAt(i - set.size()));
                i--;
            }
        }

        return maxLen;
    }
    //方法二：使用这一方法时，有边界的初始化是比不可少的
    public static int lengthOfLongestSubstring01(String s){
        if (s == null || s.length()==0){
            return 0;
        }
        int len = s.length();
        //定义存储窗口内元素的结构
        Set<Character> set = new HashSet<>();

        //初始化窗口内容和返回值
        int ans = 0;
        int rk = 0; //右边界
        set.add(s.charAt(0));
        //动态窗口，窗口滑动寻找结果
        for (int i = 0;i < len; i++){
            //右边界向右滑动，条件控制，必须满足条件指针才能够移动，不满足就去移动左指针
            while ((rk+1)<len && !set.contains(s.charAt(rk+1))){
                //处理滑动窗口中的内容
                set.add(s.charAt(rk+1));
                rk++;
            }
            ans = Math.max(rk-i+1, ans);
            //左边界向右滑动
            set.remove(s.charAt(i));
        }
        return ans;

    }
    //复习时：方法一：

}
